﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
using System.Reflection;
using System.IO;
using System.Diagnostics;
namespace RoslynEval
{
    //public class Eval
    //{
    //    Assembly assembly;
    //    Type assemblyType;
    //    MethodInfo evaluator;

    //    public static Func<Double[], Double> CreateEvalFunction(String inEquation, String[] variableNames)
    //    {
    //        Eval eval = new Eval(inEquation, variableNames);
    //        return (Double[] variableValues) => eval.CallAssembly(variableValues);
    //    }

    //    public Eval(String inEquation, String[] variableNames)
    //    {
    //        SetAssembly(inEquation, variableNames);
    //    }

    //    public void SetAssembly(String inEquation,String[] variableNames)
    //    {
    //        String variableNamesString = VariableNamesToString(variableNames);
    //        var text = "using System; class Calc { public static object Eval(" + variableNamesString + ") { return " + inEquation + "; } }";
    //        assembly = CompileAssembly(text);
    //        if (assembly == null)
    //        {
    //            return;
    //        }
    //        assemblyType = assembly.GetType("Calc");
    //        evaluator = assemblyType.GetMethod("Eval");
    //    }

    //    public Double CallAssembly(Double[] variableValues)
    //    {
    //        if (assembly == null)
    //        {
    //            return Double.NaN;
    //        }
    //        object[] objs = Functional.Maps.Map(variableValues, x => (object)x);
    //        string answer = evaluator.Invoke(null, objs).ToString();
    //        return StringToDouble(answer);
    //    }

    //    public static Double StringToDouble(String inString)
    //    {
    //        Double result;
    //        if (Double.TryParse(inString, out result) == true)
    //        {
    //            return result;
    //        }
    //        else
    //        {
    //            return Double.NaN;
    //        }
    //    }

    //    public static String VariableNamesToString(String[] variableNames)
    //    {
    //        Int32 L;
    //        String lOut="";
    //        for (L = 0; L < variableNames.Length; L++)
    //        {
    //            lOut += "Double " + variableNames[L];
    //            if (L < variableNames.Length - 1)
    //            {
    //                lOut += ",";
    //            }
    //        }
    //        return lOut;
    //    }

    //    public static Assembly CompileAssembly(String inCode)
    //    {

    //        var tree = SyntaxTree.ParseCompilationUnit(inCode);

    //        var compilation = Compilation.Create(

    //            "calc.dll",

    //            options: new CompilationOptions(assemblyKind: AssemblyKind.DynamicallyLinkedLibrary),

    //            syntaxTrees: new[] { tree },

    //            references: new[] { new AssemblyFileReference(typeof(object).Assembly.Location) });



    //        Assembly compiledAssembly;

    //        var stream = new MemoryStream();

    //        {

    //            EmitResult compileResult = compilation.Emit(stream);

    //            try
    //            {
    //                compiledAssembly = Assembly.Load(stream.GetBuffer());
    //            }
    //            catch
    //            {
    //                return null;
    //            }
    //            stream = null;
    //        }

    //        return compiledAssembly;
    //    }


    //}
}
